package tigroids.timer;

import java.util.ArrayList;
import tigroids.timer.SingleTimer.State;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainTimerActivity extends Activity {
	static final int ON_INTENT_SAVE = 2001;
	static final int ON_INTENT_SAVE_AND_START = 2002;
	static final int ON_INTENT_CANCEL = 2003;

	ArrayList<LinearLayout> timerContainers = new ArrayList<LinearLayout>();

	ClickListenerEdit clickListenerEdit = null;
	ClickListenerStart clickListenerStart = null;
	ClickListenerPause clickListenerPause = null;
	ClickListenerResume clickListenerResume = null;
	ClickListenerCancel clickListenerCancel = null;

	public MainTimerActivity() {
		clickListenerEdit = new ClickListenerEdit(this);
		clickListenerStart = new ClickListenerStart(this);
		clickListenerPause = new ClickListenerPause(this);
		clickListenerResume = new ClickListenerResume(this);
		clickListenerCancel = new ClickListenerCancel(this);
	}

	private TimerApplication getTimerApplication() {
		return (TimerApplication) super.getApplication();
	}

	private SingleTimer getTimer(int timerId) {
		return getTimerApplication().getTimer(timerId);
	}

	private void setTimerText(LinearLayout timerView, long milliseconds) {
		TextView timerTime = (TextView) timerView.findViewById(R.id.timerTime);
		String timeAsText = String.format("%02d:%02d", milliseconds
				/ (1000 * 60), (milliseconds / 1000) % 60);
		timerTime.setText(timeAsText);
	}

	class IncomingHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case TimerService.MESSAGE_WHAT_TICK_BEFORE_ELAPSED: {

				int timerId = msg.arg1;
				int millisLeft = msg.arg2;

				SingleTimer timer = getTimer(timerId);
				if (timer.getCurrentState() == State.RUNNING) {
					LinearLayout ll = getTimerView(timerId);
					setTimerText(ll, millisLeft);
				}
			}
			break;

			case TimerService.MESSAGE_WHAT_START_RINGING: {
				int timerId = msg.arg1;

				SingleTimer timer = getTimer(timerId);
				timer.setCurrentState(State.RINGING);
				timer.startMusic();

				LinearLayout container = timerContainers.get(timerId);
				container.removeAllViews();

				LinearLayout ll = createTimerRinging(timerId);
				container.addView(ll);
			}
				break;
				
			case TimerService.MESSAGE_WHAT_STOP_RINGING:{
				int timerId = msg.arg1;
				
				SingleTimer timer = getTimer(timerId);
				timer.stopMusic();
			}
			break;
			
			case TimerService.MESSAGE_WHAT_TICK_AFTER_ELAPSED: {
				int timerId = msg.arg1;
				int elapsedMillis = msg.arg2;

				SingleTimer timer = getTimer(timerId);
				if (timer.getCurrentState() == State.RINGING) {
					LinearLayout ll = getTimerView(timerId);
					setTimerText(ll, elapsedMillis);
				}
			}
			break;
			
			
			
			default:
				super.handleMessage(msg);
			}

		}
	}

	final Messenger mMessenger = new Messenger(new IncomingHandler());

	private LinearLayout createTimerInactive(int timerId) {
		LinearLayout ret = (LinearLayout) View.inflate(this,
				R.layout.single_timer_inactive, null);
		ret.setId(timerId);
		((Button) ret.findViewById(R.id.buttonEdit))
				.setOnClickListener(clickListenerEdit);
		((Button) ret.findViewById(R.id.buttonStart))
				.setOnClickListener(clickListenerStart);

		SingleTimer timer = getTimer(timerId);

		TextView timerTitle = (TextView) ret.findViewById(R.id.timerTitle);
		timerTitle.setText(timer.getTitle());

		TextView alarmType = (TextView) ret.findViewById(R.id.alarmType);
		alarmType.setText(timer.getAlarmType());

		setTimerText(ret, timer.getMillisecondsLeft());

		return ret;
	}

	private LinearLayout createTimerRunning(int timerId) {
		 LinearLayout ret = (LinearLayout) View.inflate(this,
				R.layout.single_timer_running, null);
		ret.setId(timerId);
		((Button) ret.findViewById(R.id.buttonPause))
				.setOnClickListener(clickListenerPause);
		((Button) ret.findViewById(R.id.buttonCancel))
				.setOnClickListener(clickListenerCancel);
		
		SingleTimer timer = getTimer(timerId);

		TextView timerTitle = (TextView) ret.findViewById(R.id.timerTitle);
		timerTitle.setText(timer.getTitle());

		TextView alarmType = (TextView) ret.findViewById(R.id.alarmType);
		alarmType.setText(timer.getAlarmType());

		setTimerText(ret, timer.getMillisecondsLeft());
		return ret;
	}
	
	private LinearLayout createTimerPaused(int timerId) {
		LinearLayout ret = (LinearLayout) View.inflate(this,
				R.layout.single_timer_paused, null);
		ret.setId(timerId);
		((Button) ret.findViewById(R.id.buttonResume))
				.setOnClickListener(clickListenerResume);
		((Button) ret.findViewById(R.id.buttonCancel))
				.setOnClickListener(clickListenerCancel);

		SingleTimer timer = getTimer(timerId);

		TextView timerTitle = (TextView) ret.findViewById(R.id.timerTitle);
		timerTitle.setText(timer.getTitle());

		setTimerText(ret, timer.getMillisecondsLeft());

		TextView alarmType = (TextView) ret.findViewById(R.id.alarmType);
		alarmType.setText(timer.getAlarmType());

		return ret;
	}

	private LinearLayout createTimerRinging( int timerId) {
		final LinearLayout ret = (LinearLayout) View.inflate(this,
				R.layout.single_timer_ringing, null);
		ret.setId(timerId);
		((Button) ret.findViewById(R.id.buttonCancel))
				.setOnClickListener(clickListenerCancel);

		final SingleTimer timer = getTimer(timerId);

		TextView timerTitle = (TextView) ret.findViewById(R.id.timerTitle);
		timerTitle.setText(timer.getTitle());

		TextView alarmType = (TextView) ret.findViewById(R.id.alarmType);
		alarmType.setText(timer.getAlarmType());

		setTimerText(ret, timer.getMillisecondsLeft());
		return ret;
	}

	private void createInitialViews() {
		timerContainers.add((LinearLayout) findViewById(R.id.cell1));
		timerContainers.add((LinearLayout) findViewById(R.id.cell2));
		timerContainers.add((LinearLayout) findViewById(R.id.cell3));
		timerContainers.add((LinearLayout) findViewById(R.id.cell4));

		for (int cnt = 0; cnt < TimerApplication.numberOfTimers; cnt++) {
			SingleTimer timer = getTimer(cnt);
			LinearLayout ll = null;

			switch (timer.getCurrentState()) {
			case INACTIVE:
				ll = createTimerInactive(cnt);
				break;

			case RUNNING:
				ll = createTimerRunning(cnt);
				break;

			case PAUSED:
				ll = createTimerPaused(cnt);
				break;

			case RINGING:
				throw new RuntimeException("not yet implemented");
				// break;

			default:
				throw new RuntimeException("unknown timer status");
			}

			ll.setId(cnt);
			timerContainers.get(cnt).addView(ll);
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_table);
		createInitialViews();

		getTimerApplication().messenger = mMessenger;

		TextView donateLink = (TextView) findViewById(R.id.donate);
		donateLink.setMovementMethod(LinkMovementMethod.getInstance());
		donateLink
				.setText(Html
						.fromHtml("<a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8WH3EXP3YRXTS\">Donate...</a> "));

	}

	private LinearLayout findContainer(View v) {
		View currentView = v;

		while (currentView != null) {
			for (int cnt = 0; cnt < timerContainers.size(); cnt++) {
				if (currentView == timerContainers.get(cnt)) {
					return (LinearLayout) currentView;
				}
			}
			currentView = (View) currentView.getParent();
		}
		return (LinearLayout) currentView;
	}

	LinearLayout getTimerView(int id) {
		return (LinearLayout) timerContainers.get(id).getChildAt(0);
	}

	void onButtonEdit(Button btn) {
		LinearLayout container = findContainer(btn);
		int timerId = container.getChildAt(0).getId();

		// TODO what will happen if i press the EDIT button twice?
		Intent intent = new Intent(MainTimerActivity.this,
				EditTimerActivity.class);
		intent.putExtra(TimerApplication.parameterNameTimerToEdit, timerId);

		startActivity(intent);
	}

	void startServerWithParameters(int intentStartCommand, int timerId) {
		Intent timerStarter = new Intent(this, TimerService.class);
		timerStarter.putExtra(TimerApplication.parameterNameCommand, intentStartCommand);
		timerStarter.putExtra(TimerApplication.parameterNameTimerToEdit, timerId);
		startService(timerStarter);
	}

	void onButtonStart(Button btn) {
		LinearLayout container = findContainer(btn);
		int timerId = container.getChildAt(0).getId();
		SingleTimer timer = getTimer(timerId);

		btn.setOnClickListener(null);
		container.removeAllViews();

		LinearLayout ll = createTimerRunning(timerId);
		timer.setCurrentState(State.RUNNING);
		container.addView(ll);

		startServerWithParameters(TimerService.INTENT_START_COMMAND_TIMER_START, timerId);
	}

	void onButtonPause(Button btn) {
		LinearLayout container = findContainer(btn);
		int timerId = container.getChildAt(0).getId();
		SingleTimer timer = getTimer(timerId);

		btn.setOnClickListener(null);
		container.removeAllViews();

		LinearLayout ll = createTimerPaused(timerId);
		timer.setCurrentState(State.PAUSED);
		container.addView(ll);

		startServerWithParameters(
				TimerService.INTENT_START_COMMAND_TIMER_PAUSE, timerId);
	}

	public void onButtonResume(Button btn) {
		LinearLayout container = findContainer(btn);
		int timerId = container.getChildAt(0).getId();
		SingleTimer timer = getTimer(timerId);

		btn.setOnClickListener(null);
		container.removeAllViews();

		LinearLayout ll = createTimerRunning(timerId);
		timer.setCurrentState(State.RUNNING);
		container.addView(ll);

		startServerWithParameters(
				TimerService.INTENT_START_COMMAND_TIMER_RESUME, timerId);
	}

	void onButtonCancel(Button btn) {
		LinearLayout container = findContainer(btn);
		int timerId = container.getChildAt(0).getId();
		SingleTimer timer = getTimer(timerId);

		timer.setMillisecondsLeft(timer.getMilliseconds());
		btn.setOnClickListener(null);
		container.removeAllViews();

		if (timer.getCurrentState() == State.RINGING) {
			timer.stopMusic();
		}

		LinearLayout ll = createTimerInactive(timerId);
		timer.setCurrentState(State.INACTIVE);
		container.addView(ll);

		startServerWithParameters(TimerService.INTENT_START_COMMAND_TIMER_CANCEL, timerId);
	}


	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);

		int command = (Integer) intent.getExtras().get(
				TimerApplication.parameterNameCommand);
		switch (command) {

		case ON_INTENT_SAVE: {
			Integer timerId = (Integer) intent.getExtras().get(
					TimerApplication.parameterNameTimerToEdit);

			LinearLayout container = timerContainers.get(timerId);
			SingleTimer timer = getTimer(timerId);
			timer.setMillisecondsLeft(timer.getMilliseconds());
			container.removeAllViews();

			if (timer.getCurrentState() == State.RINGING) {
				timer.stopMusic();
			}

			LinearLayout ll = createTimerInactive(timerId);
			timer.setCurrentState(State.INACTIVE);
			container.addView(ll);
		}
			break;

		case ON_INTENT_SAVE_AND_START: {
			Integer timerId = (Integer) intent.getExtras().get(
					TimerApplication.parameterNameTimerToEdit);

			LinearLayout container = timerContainers.get(timerId);
			SingleTimer timer = getTimer(timerId);
			timer.setMillisecondsLeft(timer.getMilliseconds());
			container.removeAllViews();

			LinearLayout ll = createTimerRunning(timerId);
			timer.setCurrentState(State.RUNNING);
			container.addView(ll);

			startServerWithParameters(
					TimerService.INTENT_START_COMMAND_TIMER_START, timerId);
		}
			break;

		case ON_INTENT_CANCEL: {
			// do nothing
		}
			break;

		default:
			Log.e(TimerApplication.logAppId,
					"Unknown event in TestTimerApplication::onNewIntent");
		}

	}

}
